import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;


/**
 * Class that parses the line that is written in the chat and
 * then calls the appropriate method for each listener.
 * @author Tobias Johansson
 *
 */
public class LolBotMessageParser {
	private List<LolBotEventListener> listenerList;
	
	public LolBotMessageParser(){
		listenerList = new ArrayList<LolBotEventListener>();
	}
	
	/**
	 * Parse the line that was written in the chat. This is a
	 * long method, please don't hit me for that.
	 * @param message The line that was written in the chat.
	 */
	public void parse(String channel, String message){
		System.out.println(message);
		
		/////////////////////////////////////////////////
		//  The following is for finding the source nick
		//  and command. Just a lot of crap.
		/////////////////////////////////////////////////
		String sourceNick = "";
        String[] lineWords =
                (message.substring(message.indexOf(" :") + 2)).split(" ");
        String command = lineWords[0];
        List<String> arguments = new ArrayList<String>();
        if(lineWords.length > 1){
	        for(int i = 1; i < lineWords.length; i++){
	        	arguments.add(lineWords[i]);
	        }
        }
        StringTokenizer tokenizer = new StringTokenizer(message);
        String senderInfo = tokenizer.nextToken();

        int exclamation = senderInfo.indexOf("!");
        int at = senderInfo.indexOf("@");
        if (senderInfo.startsWith(":")) {
            if (exclamation > 0 && at > 0 && exclamation < at) {
                sourceNick = senderInfo.substring(1, exclamation);
            }
        }

        if (sourceNick.startsWith(":")) {
            sourceNick = sourceNick.substring(1);
        }
        /////////////////////////////////////////////////
        /////////////////////////////////////////////////
        
        //Create the LolBotEvent that we will send to the listener.
        LolBotEvent e = new LolBotEvent(this, sourceNick, arguments, null);
        
        // Here we start to call the appropriate methods.
        if (message.startsWith("PING")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onPing();
        	}
        } else if (message.indexOf("JOIN ") > -1){
        	for(LolBotEventListener listener : listenerList){
        		listener.onJoin(e);
        	}
        } else if (command.equals(",exit")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onExit(e);
        	}
        } else if (message.indexOf("KICK " + channel + " LolBot") > -1){
        	for(LolBotEventListener listener : listenerList){
        		listener.onLolBotKicked(e);
        	}
        } else if (command.equals(",op")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onOp(e);
        	}
        } else if (command.equals(",say")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onSay(e);
        	}
        } else if (command.equals(",me")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onMe(e);
        	}
        } else if (command.equals(",addOp")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onAddOp(e);
        	}
        } else if (command.equals(",delOp")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onDelOp(e);
        	}
        } else if (command.equals(",listOfOps")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onListOfOps(e);
        	}
        } else if (command.equals(",addBadWord")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onAddBadWord(e);
        	}
        } else if (command.equals(",delBadWord")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onDelBadWord(e);
        	}
        } else if (command.equals(",listOfBadWords")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onListOfBadWords(e);
        	}
        } else if (command.equals(",ignore")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onIgnore(e);
        	}
        } else if (command.equals(",unignore")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onUnignore(e);
        	}
        } else if (command.equals(",help")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onHelp(e);
        	}
        } else if (command.equals(",nithander")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onNithander(e);
        	}
        } else if (command.equals(",sing")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onSing(e);
        	}
        } else if (command.equals(",stopSinging")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onStopSinging(e);
        	}
        } else if (command.equals(",op")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onOp(e);
        	}
        } else if (command.equals(",date")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onDate(e);
        	}
        } else if (command.equals(",phoneHome")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onPhoneHome(e);
        	}
        } else if (command.equals(",blopp")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onBlopp(e);
        	}
        } else if (command.equals(",russian_roulette")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onRussianRoulette(e);
        	}
        } else if (command.equals(",click")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onClick(e);
        	}
        } else if (command.equals(",spin")){
        	for(LolBotEventListener listener : listenerList){
        		listener.onSpin(e);
        	}
        } else if (message.toLowerCase().replaceAll("[^A-Za-z0-9]", "")
        		.indexOf("rendezvous") > -1){
        	//Check if someone wrote the word "rendezvous" in the chat.
        	for(LolBotEventListener listener : listenerList){
        		listener.onRendezvous(e);
        	}
        } else if (message.toLowerCase().replaceAll("[^A-Za-z0-9]", "")
        		.indexOf("messerschmidt") > -1){
        	//Check if someone wrote the word "messerschmidt" in the chat.
        	for(LolBotEventListener listener : listenerList){
        		listener.onMesserschmidt(e);
        	}
        } else {
        	//Check for bad words. Hacky, sorry for that :(
        	for(String word : lineWords){
        		String trimmedWord = word.toLowerCase()
        				.replaceAll("[^A-Za-z0-9]", "");
        		if(LolBotCommandHandler.badWordsList.contains(trimmedWord)){
        			e = new LolBotEvent(this, sourceNick, arguments, trimmedWord);
        			for(LolBotEventListener listener : listenerList){
        				listener.onBadWord(e);
        			}
        		}
        	}
        }
	}
	
	/**
	 * Add a listener to the listener list. This listener will get the
	 * appropriate method called when the corresponding command
	 * is written in the chat.
	 * @param listener The listener to add to the listener list.
	 */
	public void addEventListener(LolBotEventListener listener){
		listenerList.add(listener);
	}
	
	/**
	 * Remove a listener from the listener list. This listener will no
	 * longer have any methods called when something is written in the chat.
	 * @param listener The listener to be removed from the listener list.
	 */
	public void removeEventListener(LolBotEventListener listener){
		listenerList.remove(listener);
	}
}
